package com.bsj.sipgateway.web.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsj.power.common.config.exception.ApiException;
import com.bsj.power.common.config.global.JsonResult;
import com.bsj.power.common.config.global.JsonResultEnum;
import com.bsj.power.common.def.entity.file.FileLog;
import com.bsj.power.common.def.entity.file.FileLogMake;
import com.bsj.power.common.def.entity.job.Job;
import com.bsj.power.common.def.enums.FileTypeEnum;
import com.bsj.power.common.def.vo.video.file.*;
import com.bsj.power.common.mapper.FileLogMakeMapper;
import com.bsj.power.common.mapper.FileLogMapper;
import com.bsj.power.common.mapper.JobMapper;
import com.bsj.power.common.util.DateUtils;
import com.bsj.power.common.util.StringUtils;
import com.bsj.sipgateway.web.service.IFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : zhuojie.c
 * @version V1.0
 * @Description: 文件上传模块
 * @date Date : 2024年08月12日
 */
@Slf4j
@Service("fileServiceImpl")
public class FileServiceImpl implements IFileService {

    /**
     * 附件地址
     */
    @Value("${file.path}")
    private String path;

    @Resource
    private FileLogMapper fileLogMapper;

    @Resource
    private FileLogMakeMapper fileLogMakeMapper;

    @Resource
    private JobMapper jobMapper;

    /**
     * 文件上传
     *
     * @param file
     * @param fileType
     * @return
     */
    @Override
    public JsonResult upload(MultipartFile file, Integer fileType, String filename) {
        if (file == null || fileType == null) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR, "file & fileType 不能为空");
        }
        // 文件名
        String originalFileName = file.getOriginalFilename();
        if (originalFileName == null) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR, "文件名异常，不能为空");
        }
        // 判断文件名
        if (originalFileName.lastIndexOf('.') == -1) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR, "文件名异常，格式后缀缺失");
        }
        // 文件后缀
        String suffixName = originalFileName.substring(originalFileName.lastIndexOf('.'));
        // 日期格式
        String date = DateUtils.dateToStr(DateUtils.TIME_STANDARD_FORMAT_YMD, new Date());
        // 文件存储路径
        String filePath = path;
        // 文件类型存储路径
        String fileTypePath = "/" + FileTypeEnum.getByValue(fileType) + "/" + date + "/";
        File folder = new File(filePath + fileTypePath);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        // 文件名
//        String fileName = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + suffixName;
        String fileName = filename;
        File destinationFile = new File(filePath + fileTypePath + fileName);
        try {
            file.transferTo(destinationFile);
        } catch (IOException e) {
            throw new ApiException(JsonResultEnum.FAIL, "文件上传失败！");
        }
        return JsonResult.success(fileTypePath + fileName);
    }

    @Override
    public JsonResult<FileListVO> addFile(FileAddVO fileAddVO) {
        FileLog fileLog = new FileLog();
        if (StringUtils.isBlank(fileAddVO.getFileName())) {
            fileAddVO.setFileName(DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_FORMATTER));
        }
        if (fileAddVO.getJobId() != null) {
            Job job = jobMapper.selectById(fileAddVO.getJobId());
            if (job == null) {
                throw new ApiException(JsonResultEnum.JOB_INFO_IS_NULL);
            }
        }
        BeanUtils.copyProperties(fileAddVO, fileLog);
        // 文件时间为当前时间
        fileLog.setFileTime(new Date());
        if (fileLogMapper.insert(fileLog) > 0) {
            FileListVO fileListVO = new FileListVO();
            BeanUtils.copyProperties(fileLog, fileListVO);
            return JsonResult.success(fileListVO);
        } else {
            return JsonResult.fail();
        }
    }

    @Override
    public JsonResult deleteFile(Long id) {
        if (fileLogMapper.deleteById(id) > 0) {
            return JsonResult.success();
        } else {
            return JsonResult.fail();
        }
    }

    @Override
    public JsonResult fileList(FileSearchVO fileSearchVO) {
        List<FileListVO> fileListVOList = new ArrayList<>();
        IPage<FileLog> fileLogPage = new Page<>(fileSearchVO.getPageNumber(), fileSearchVO.getPageSize());
        QueryWrapper<FileLog> queryWrapper = new QueryWrapper<>();
        if (fileSearchVO.getFileType() != 3) {
            queryWrapper.eq("file_type", fileSearchVO.getFileType());
        }
        if (StringUtils.isNotEmpty(fileSearchVO.getDeviceId())) {
            queryWrapper.eq("device_id", fileSearchVO.getDeviceId());
        }
        if (fileSearchVO.getStartTime() != null && fileSearchVO.getEndTime() != null) {
            queryWrapper.between("file_time", fileSearchVO.getStartTime(), fileSearchVO.getEndTime());
        }
        if (StringUtils.isNotEmpty(fileSearchVO.getEventName())) {
            queryWrapper.like("event_name", fileSearchVO.getEventName().trim());
        }
        if (StringUtils.isNotEmpty(fileSearchVO.getEventReason())) {
            queryWrapper.like("event_reason", fileSearchVO.getEventReason().trim());
        }
        if (StringUtils.isNotEmpty(fileSearchVO.getPersonResponsible())) {
            queryWrapper.like("personResponsible", fileSearchVO.getPersonResponsible().trim());
        }
        queryWrapper.orderByDesc("create_time");
        IPage<FileLog> iPage = fileLogMapper.selectPage(fileLogPage, queryWrapper);
        List<FileLog> fileLogList = iPage.getRecords();
        long total = iPage.getTotal();
        if (CollectionUtil.isNotEmpty(fileLogList)) {
            Map<Long, String> jobNumMap = new HashMap<>();
            List<Long> jobIdList = fileLogList.stream().filter(v -> v.getJobId() != null).mapToLong(FileLog::getJobId).boxed().distinct().collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(jobIdList)) {
                List<Job> jobList = jobMapper.selectList(new QueryWrapper<Job>().in("job_id", jobIdList));
                jobNumMap = jobList.stream().collect(Collectors.toMap(Job::getJobId, Job::getJobNum));
            }
            Map<Long, String> finalJobNumMap = jobNumMap;
            fileLogList.forEach(v -> {
                FileListVO fileListVO = new FileListVO();
                BeanUtils.copyProperties(v, fileListVO);
                if (v.getJobId() != null) {
                    fileListVO.setJobNum(finalJobNumMap.getOrDefault(v.getJobId(), ""));
                }
                fileListVOList.add(fileListVO);
            });
        }
        return JsonResult.success(fileListVOList, total);

    }

    /**
     * 添加视频标记内容
     *
     * @param vo
     * @return
     */
    @Override
    public JsonResult addMakeFile(FileMakeAddVO vo) {
        FileLogMake fileLogMake = new FileLogMake();
        BeanUtils.copyProperties(vo, fileLogMake);
        if (fileLogMakeMapper.insert(fileLogMake) > 0) {
            return JsonResult.success();
        } else {
            return JsonResult.fail();
        }
    }

    /**
     * 批量删除视频标记内容
     *
     * @param ids
     * @return
     */
    @Override
    public JsonResult deleteMakeFile(Long[] ids) {
        if (fileLogMakeMapper.deleteBatchIds(Arrays.asList(ids)) > 0) {
            return JsonResult.success();
        } else {
            return JsonResult.fail();
        }
    }

    /**
     * 根据视频内容ID获取标记记录集合
     *
     * @param fileLogId
     * @return
     */
    @Override
    public JsonResult<List<FileMakeListVO>> makeFileList(Long fileLogId) {
        List<FileLogMake> fileLogMakes = fileLogMakeMapper.selectList(Wrappers.<FileLogMake>lambdaQuery()
                .eq(FileLogMake::getFileLogId, fileLogId));
        List<FileMakeListVO> result = new ArrayList<>();
        fileLogMakes.stream().forEach(item -> {
            FileMakeListVO makeVo = new FileMakeListVO();
            BeanUtils.copyProperties(item, makeVo);
            result.add(makeVo);
        });
        return JsonResult.success(result, result.size());
    }

}
